#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

void Print(sigset_t& pending)
{
    for(int sig = 31;sig >= 1;sig--)
    {
        if(sigismember(&pending,sig))
        {
            std::cout << "1";
        }
        else
        {
            std::cout << "0";
        }
    }
    std::cout << "\n";
}

void handler(int signum)
{
    std::cout << "get a sig: " << signum << std::endl;
    while(true)
    {
        sigset_t pending;
        sigpending(&pending);

        Print(pending);
        sleep(1);
        //break;
    }
    exit(1);
}

int main()
{
    struct sigaction act,oact;
    act.sa_handler = handler;
    sigemptyset(&act.sa_mask); // 初始化信号集
    //sigaddset(&act.sa_mask,3); // 将3号信号添加到阻塞信号集
    // 将2号信号添加到阻塞信号集，如果进程再次接收到2号信号，它将被阻塞
    // 直到handler函数执行完毕或信号被解除阻塞
    //sigaddset(&act.sa_mask,2); // 如果你还想处理2号(OS对2号自动屏蔽)，同时对其他信号也进行屏蔽
    act.sa_flags = 0;

    // 使用sigaction为1到31号的每个信号设置了一个相同的处理函数handler
    for(int i=1;i<=31;i++)
         sigaction(i,&act,&oact);
    //sigaction(2,&act,&oact);

    while(true)
    {
        std::cout << "I am a process,pid: " << getpid() << std::endl;
        sleep(1);
    }
    return 0;
}

// volatile int gflag = 0; // 保持内存可见性，一直从内存加载到CPU

// void changedata(int sig)
// {
//     std::cout << "get a sig: " << sig << ",change gflag 0->1 " << std::endl;
//     gflag = 1;
// }

// int main()
// {
//     signal(2,changedata);
//     while(!gflag); // 不需要其他代码
//     std::cout << "process quit formal!" << std::endl;
//     return 0;
// }

// void notice(int sig)
// {
//     std::cout << "get a sig: " << sig << ",pid: " << getpid() << std::endl;
// }

// void notice(int sig)
// {
//     std::cout << "get a sig: " << sig << ",pid: " << getpid() << std::endl;
//     while(true)
//     {
//         pid_t rid = waitpid(-1,nullptr,WNOHANG); // 阻塞 -> 非阻塞
//         if(rid > 0)
//         {
//             std::cout << "wait child success pid: " << getpid() << std::endl;
//         }
//         else if(rid < 0)
//         {
//             std::cout << "wait child failed!!!" << std::endl; 
//             break;
//         }
//         else
//         {
//             std::cout << "wait child success done " << std::endl;
//             break;
//         }
//     }
   
// }

// void DoOtherThing()
// {
//     std::cout << "DoOtherThing()~" << std::endl;
// }

// int main()
// {
//     signal(SIGCHLD,notice);
//     for(int i=0;i<10;i++)
//     {
//         pid_t id = fork();
//         if(id == 0)
//         {
//             // child
//             std::cout << "I am child process,pid: " << getpid() << std::endl;
//             sleep(3);
//             exit(1);
//         }
//     }
    
//     // father
//     while(true)
//     {
//         DoOtherThing();
//         sleep(1);
//     }
//     return 0;
// }